package com.hoe.tsb.fraft.client;

import com.hoe.tsb.block.Block;
import com.hoe.tsb.block.BlockChainApi;
import com.hoe.tsb.fraft.listener.FRaftClientListener;
import com.hoe.tsb.web.bean.Trace;

/**
 * <p>
 * FRaft客户端
 * </p>
 *
 * @author hoe
 * @version 1.0
 * @date 2022/11/21
 */
public interface FRaftClient extends BlockChainApi {

    /**
     * 给应用层添加客户端的监听用<br/>
     * 当出现客户端状态变更时，冒泡向上响应
     * @param callback 监听
     */
    void addListener(FRaftClientListener callback);

    /**
     * 提交数据到FRaft<br/>
     * 节点收到提交请求后立即进行校验：各parent是否存在，该数据是否存在（计算hash）<br/>
     * 此时就可以响应客户端了，之后的都是异步操作<br/>
     * 校验通过后非Leader节点将数据转发给Leader<br/>
     * Leader对数据进行校验（有可能2次校验），校验不通过直接拒绝
     * @param trace 待提交的溯源数据 TODO 直接耦合Trace，后续可以考虑解耦后使用byte[]，用通用的消息体进行封装
     * @return 如果是异步消息，返回null，如果是同步消息返回溯源Hash和签名以及随机数
     */
    Object submit(Trace trace);

    /**
     * 获取区块链块高
     * @return 块高
     */
    long getHeight();

    /**
     * 根据区块Hash获取区块数据
     * @param blockHash 区块hash
     * @return 区块数据
     */
    Block getBlock(String blockHash);

    /**
     * 根据溯源Hash查询区块Hash
     * @param traceHash 溯源Hash
     * @return 区块Hash
     */
    String getBlockHash(String traceHash);

    /**
     * 获取顶层区块数据
     * @return 顶层区块数据
     */
    Block getTopBlock();

}
